package com.healthbox.appointmentservice.service.proxy;

import com.healthbox.appointmentservice.DVO.AppointmentInfoDVO;
import com.healthbox.appointmentservice.config.AppointmentConfig;
import com.healthbox.appointmentservice.service.AppointmentInfoModifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/**
 * @author pengpeng
 * @date 2022/5/22
 * 这是一个添加预约的代理类
 */
@Service
@Slf4j
public class AppointmentInfoModifyProxy implements AppointmentInfoModifyService {
    @Autowired
    private AppointmentInfoModifyService appointmentInfoModifyImpl;

    @Autowired
    private ValueOperations<String, Integer> appointmentNumberOps;
    @Autowired
    private AppointmentConfig config;

    /**
     * 添加预约
     * 使用redis加上消息队列来做预约（类似秒杀的效果）
     * 1. redis中保存一个资源预定人数的计数, 消息队列中存储要执行的操作
     * 2. 当用户预定一个资源时，不直接写入数据库，而是在消息队列中的放入一个待执行的操作，然后将资源计数加一，然后就可以返回了
     * 3. 另有一个线程可以按照自身处理能力来拉取消息队列中的消息，并真正执行数据库的写入操作
     * @param userPhone
     * @param aLid
     * @return
     */
    @Override
    public AppointmentInfoDVO addAppointment(String userPhone, Long aLid) {
        String key = config.getPrefix() + aLid;

        // 发送消息 TODO
        log.info("TODO: 使用消息队列削峰填谷， 取代直接调用");

        // 更新redis缓存

        Integer n = appointmentNumberOps.get(key);
        if(n!=null) {
            appointmentNumberOps.increment(key, 1L);
        }

        return appointmentInfoModifyImpl.addAppointment(userPhone, aLid);
    }
}
